#include "gcs1.h"

void detener(int p){
    cout << "Imposible obtener una solución en el tiempo otorgado" << endl;
    exit(0);
}

Grafo *leerGrafo(char * nombreArchivo){
    ifstream archivo(nombreArchivo);

    if (!archivo) {
        cerr << "El archivo " << nombreArchivo << " no existe" << endl;
        exit(0);
    }

    string linea;
    int numNodos = -1, numArcos = -1;
    Grafo *grafo = 0;

    while (archivo.good()){
        getline(archivo, linea);

        // Se omiten los comentarios, valores de nodos, descriptores geométricos,
        // coordenadas del nodo y parámetros
        if(   'c' == linea[0] || 'n' == linea[0] || 'd' == linea[0]
           || 'v' == linea[0] || 'x' == linea[0] || 0 == linea.compare("")){
            continue;
        }

        istringstream istream(linea);
        string dummy;

        // Leer el tamaño del grafo e instanciarlo
        if ('p' == linea[0]){
            if (0 != grafo){
                cerr << "Definición de tamaño encontrada dos veces en el archivo '" << nombreArchivo << "'." << endl;
                exit(0);
            }
            istream >> dummy >> dummy >> numNodos >> numArcos;
            //cout << "Creando el grafo con " << numNodos << " nodos y " << numArcos << " arcos" << endl;
            grafo = new Grafo(numNodos);
            continue;
        }

        // Leer y agregar un nuevo arco
        int fuente, destino;
        if ('e' == linea[0]){
            istream >> dummy >> fuente >> destino;
            //cout << "Agregando arco " << fuente << "-" << destino << endl;
            grafo->agregarArco(fuente, destino);
            continue;
        }

        //DIMACS Standard no admite más tipos de opciones
        cerr << "Línea '" << linea << "' no esperada en el archivo '" << nombreArchivo << "'." << endl;
        exit(0);
    }

    return grafo;
}

int main(int argc, char **argv){

    bool algBrown = false;
    bool algDsat = false;
    bool algKorm = false;
    bool algBrelaz = false;
    int t = 3600;
    char *nombreArchivo = (char*)"";
    time_t inicio, fin;
    FILE *salidas;
    clock_t begin;
    
    for (int i = 0; i < argc; ++ i){
        if (0 == strcmp("-d", argv[i])){
            algDsat = true;
        } else if (0 == strcmp("-b", argv[i])) {
            algBrown = true;
        } else if(0 == strcmp("-k", argv[i])){
            algKorm = true;
        } else if(0 == strcmp("-z", argv[i])){
            algBrelaz = true;
        } else if (0 == strcmp("-t", argv[i])) {
            if (i + 1 == argc) {
                cerr << "Se esperaba el tiempo después de -t" << endl;
                exit(0);
            }
            ++ i;
            t = atoi(argv[i]);
        } else if (i + 1 == argc) {
            nombreArchivo = argv[i];
        }
    }

    // Establecer la alarma
    signal(SIGALRM, detener);
    alarm(t);

    Grafo *grafo = leerGrafo(nombreArchivo);
    grafo->sortAdyacentes();
    //cout << "Iniciando la corrida del algoritmo " << (algBrown ? "BROWN" : "DSATUR") << endl;
    begin = clock();
    if (algBrown) {
        grafo->colorearBrown();
    } else if(algDsat){
        dsatur(grafo);
    } else if(algKorm){
        grafo->colorearBrownKorman();
    } else if(algBrelaz){
        brelaz(grafo);
    }

    //grafo->imprimir();
    cout << "En un tiempo de: " << (float)(clock() - begin) / (CLOCKS_PER_SEC / 1000) << " milisegundos" << endl;
    cout << "¿Tiene coloracion valida? " << (grafo->tieneColoracionValida() ? "Si" : "No") << endl;
    cout << "Numero de colores: " << grafo->getColorMax() + ((algBrown || algKorm) ? 1 : 0) << endl;

    //Salida especial para las pruebas que se están corriendo
    //cout << nombreArchivo << "," << grafo->getColorMax() + 1 << "," << (float)(clock() - begin) / (CLOCKS_PER_SEC / 1000) << ";" << endl;
    return 0;
}